//! GraphQL type definitions
//! 
//! This module contains GraphQL type definitions and utilities.

use async_graphql::{SimpleObject, InputObject, Enum};

/// A minimal user type for demo query
#[derive(SimpleObject, Debug, Clone)]
pub struct UserStub {
    /// Username (from users.name column)
    pub name: String,
}
use serde::{Deserialize, Serialize};

/// Order direction for sorting
#[derive(Enum, Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
pub enum OrderDirection {
    /// Ascending order
    Asc,
    /// Descending order
   Desc,
}

/// Pagination input
#[derive(InputObject, Debug, Clone)]
pub struct PaginationInput {
    /// Number of items to return
    pub limit: Option<i32>,
    /// Number of items to skip
    pub offset: Option<i32>,
}

impl Default for PaginationInput {
    fn default() -> Self {
        Self {
            limit: Some(50),
            offset: Some(0),
        }
    }
}

/// Connection info for pagination
#[derive(SimpleObject, Debug, Clone)]
pub struct ConnectionInfo {
    /// Total count of items
    pub total_count: i32,
    /// Whether there are more items
    pub has_next_page: bool,
    /// Whether there are previous items
    pub has_previous_page: bool,
}

/// Generic connection type for pagination
#[derive(SimpleObject, Debug, Clone)]
pub struct JsonConnection {
    /// List of items
    pub nodes: Vec<serde_json::Value>,
    /// Connection information
    pub page_info: ConnectionInfo,
}

impl JsonConnection {
    /// Create a new connection
    pub fn new(nodes: Vec<serde_json::Value>, total_count: i32, limit: i32, offset: i32) -> Self {
        let has_next_page = offset + limit < total_count;
        let has_previous_page = offset > 0;
        Self {
            nodes,
            page_info: ConnectionInfo {
                total_count,
                has_next_page,
                has_previous_page,
            },
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_pagination_input_default() {
        let pagination = PaginationInput::default();
        assert_eq!(pagination.limit, Some(50));
        assert_eq!(pagination.offset, Some(0));
    }
    
    #[test]
    fn test_connection_creation() {
        let nodes = vec![serde_json::json!("item1"), serde_json::json!("item2")];
        let connection = JsonConnection::new(nodes.clone(), 10, 5, 0);
        assert_eq!(connection.nodes, nodes);
        assert_eq!(connection.page_info.total_count, 10);
        assert_eq!(connection.page_info.has_next_page, true);
        assert_eq!(connection.page_info.has_previous_page, false);
    }
    
    #[test]
    fn test_connection_pagination() {
        let nodes = vec![serde_json::json!("item1")];
        let connection = JsonConnection::new(nodes, 10, 5, 5);
        
        assert_eq!(connection.page_info.has_next_page, false);
        assert_eq!(connection.page_info.has_previous_page, true);
    }
}